package com.example.scala.chapter4

/**
 *
 * Description:
 *
 * Create by lucienoz on 2021/10/16.
 * Copyright © 2021 lucienoz. All rights reserved.
 */
object chapter03 {
	def main(args : Array[String]) : Unit = {
		//函数参数为函数,有且只有当参数函数的形参列表为1个时()可省略
		//参数函数要求无参数
		def foo(bar:() => Unit):Unit={ //参数函数要求无参函数时，括号不可以被省略，在函数体进行调用时需使用"函数名+()"进行调用，否则Scala将认为是使用函数变量 相当于"函数名 _",而不是调用该函数
			bar()  //当定义函数无参函数"()"未省略为入参函数对象地址，调用函数应+"()",此条规则在函数为参数生效
		}

		foo( () => println("bar-----")) //传入函数参数时 "()=>"不能省略


		def foo1(bar: => Unit):Unit={ //"bar:() => Unit","()"省略后"bar:=>返回值"的不为无参函数做入参，而是相当于"控制抽象"，要求传入的为代码块即传参时传入为代码块
			bar //在这种情况下 bar相当与{代码块；代码块}等结构
		}

		foo1( println("bar")) //传入函数参数时 "()=>"不能省略,foo( println("bar"))报错


		//参数函数要求只有一个参数
		def foo2(bar:(String)=>Unit):Unit = { //1. 参数函数要求一个入参变量,当入参函数对象形参列表有且只有一个参数时"()"可以省略
			bar("bar")
		}
		foo2( (bar) => { //声明匿名函数作为入参
			println(bar)
		})

		def bar(str:String) : Unit ={ //声明一个函数，作为foo2函数的入参
			println(str)
		}

		foo2(bar)  //入参方式一
		foo2(bar _) //入参方式二 ，通过函数名 + "_",明确告知入参为函数对象

		def foo3(bar:String=>Unit):Unit = { //2. 参数函数要求一个入参变量,当入参函数对象形参列表有且只有一个参数时"()"可以省略
			bar("bar") //函数体的入参必须加()，不可省略,只有A.func(B) 可以简化为 A func B
		}



		//参数函数要求两个参数及以上
		def foo4(bar:(Int,Int)=>String):Unit={ //声明入参函数入参时"()"不可省略
			bar(1,2)
		}

		//函数入参函数变量入参为可变参数,不建议使用，工具报错但可进行编译
		//可变参数在底层为Seq类型但是,在调用时不能直接入Seq类型参数到函数中否则在编译时报类型错误
		def foo5(bar:(String,Int*)=>String):Unit={
			println ( bar ( "test\t", 2 ,2) )// 编译器 报错 但可执行
//			println ( bar ( "test", Seq[Int] ( 1 ) ) )// Error 报错 类型错误，提示函数要求Int，发现传参为Seq[Int]，类型不匹配
		}

		foo5((str,listInt : Seq[Int])=>{str*listInt.sum})

		//函数入参变量为可变函数对象

		def foo6(bar:()=>String*)={
			for (elem <- bar) {
				println ( elem () )
			}
		}

		foo6(()=>{"hello"},
				 ()=>"world")

//
//		def foo3(bar:String):String={
//			bar.mkString(",")
//		}
//
//		println ( foo3 ( {
//			println ( "foobar" )
//			println ( "foobar" )
//			"foobar"
//		} ) )

	}

}
